package cloud.xlh.my_system.config.Idempotent;

import cloud.xlh.my_system.annotation.Idempotent;
import cloud.xlh.my_system.exception.NotExistException;
import cloud.xlh.my_system.middle_aware.redis.utils.RedisUtil;
import cloud.xlh.my_system.service.TokenService;
import com.sun.istack.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created with IntelliJ IDEA.
 *
 * @ project name : xlh_osms
 * @ Author: XuLeHuang
 * @ Date: 2022/5/27 16:23
 * @ Description:
 */
@Component
public class IdempotentInterceptor implements HandlerInterceptor {

    // 注解的作用就是起一个标识的作用，使用拦截器可以拦截方法，然后方法可以获取到注解，判断注解上的方法是否是我们想要的注解，
    // 是：执行我们需要的逻辑；不是：注解放行或者拦截

    @Autowired
    private TokenService tokenService;

    //预处理回调方法，实现处理器的预处理（如检查登陆），第三个参数为响应的处理器，自定义Controller的方法对象
    //返回值：true表示继续流程（如调用下一个拦截器或处理器）；false表示流程中断（如登录检查失败），
    // 不会继续调用其他的拦截器或处理器，此时我们需要通过response来产生响应；
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // com.lkun.controller.IndexController#hello1()
        //System.out.println(handler);
        // 思路：先把错误的情况全部排除
        if (!(handler instanceof HandlerMethod)){
            return true;
        }
        Idempotent idempotent = ((HandlerMethod) handler).getMethodAnnotation(Idempotent.class);
        if (idempotent == null){
            return true;
        }
        // 获取到了方法上的注解，然后怎么办呢，我们就调用TokenService的验证方法，验证下，看是否符合条件
        try {
            return tokenService.checkToken(request);
        } catch (NotExistException e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * This implementation is empty.
     */
    // 在业务处理器处理请求完成之后，生成视图之前执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           @Nullable ModelAndView modelAndView) throws Exception {
        if (!(handler instanceof ResourceHttpRequestHandler)) {
            Idempotent idempotent = ((HandlerMethod) handler).getMethodAnnotation(Idempotent.class);
            if (idempotent != null){
                tokenService.updateToken(request);
            }
        }
    }

}

